/**
 * Created by Ysssssss on 2021/4/16.
 */
import React, { useEffect, useRef } from 'react';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { Tag } from "antd";

export const CustomizeDndProvider = props => {
    const { children } = props
    return (
        <DndProvider backend={HTML5Backend}>
            { children }
        </DndProvider>
    )
}

let timestamp = 0
let _offset = {x:0, y:0}
let hoverHandle = (offset) => Date.now() - timestamp > 100 &&
    (Math.abs(_offset.x - offset.x) > 50 || Math.abs(_offset.y - offset.y) > 50 || Date.now() - timestamp > 1000) // 防止因长宽不同，重新渲染后仍然触发hover

const useDropFunc = ({ type, id, moveItemFunc }) => useDrop({
    accept: type,
    hover(item, monitor) {
        let offset = monitor.getClientOffset()
        if (item.id !== id && hoverHandle(offset)) {
            console.log(`item: ${item.id}, id: ${id}`)
            moveItemFunc(item.id, id);
            timestamp = Date.now()
            _offset = offset
        }
    },
})

const useDragFunc = ({ type, id }) => useDrag({
    type,
    item: { id },
    collect: monitor => ({
        isDragging: monitor.isDragging(),
    }),
});

export const DraggableTableRow = ({id, dragRef, type, moveItemFunc, className, style, ...restProps }) => {
    if (!type) {
        return <tr className={className} style={style} {...restProps} />
    }
    const ref = useRef();
    const [, drop] = useDropFunc({ id, type, moveItemFunc })
    const [{ isDragging }, drag, preview] = useDragFunc({ id, type })
    useEffect(() => {
        preview(ref)
        drop(ref)
        drag(dragRef || ref)
    }, [ref])
    return (
        <tr
            key={id}
            ref={ref}
            className={`${className} opa-transition-off${isDragging ? ' opa-0' : ''}`}
            style={style || {}}
            {...restProps}
        />
    )
}

export const DraggableTag = ({ id, dragRef, type, moveItemFunc, className, style, ...restProps  }) => {
    if (!type) {
        return <Tag className={className} style={style} {...restProps} />
    }
    const ref = useRef();
    const [, drop] = useDropFunc({ id, type, moveItemFunc })
    const [{ isDragging }, drag, preview] = useDragFunc({ id, type })
    useEffect(() => {
        preview(ref)
        drop(ref)
        drag(dragRef || ref)
        console.log('test aaa')
    }, [ref])
    return (
        <Tag
            key={id}
            ref={ref}
            className={`${className} opa-transition-off${isDragging ? ' opa-0' : ''}`}
            {...restProps}
        />
    )
}

export const DraggableDiv = ({ id, dragRef, previewRef, type, moveItemFunc, className, style, ...restProps  }) => {
    if (!type) {
        return <div className={className} style={style} {...restProps} />
    }
    const ref = useRef();
    const [, drop] = useDropFunc({ id, type, moveItemFunc })
    const [{ isDragging }, drag, preview] = useDragFunc({ id, type })
    useEffect(() => {
        preview(previewRef || ref)
        drop(ref)
        drag(dragRef || ref)
    }, [ref])
    return (
        <div
            key={id}
            ref={ref}
            className={`${className} opa-transition-off${isDragging ? ' opa-0' : ''}`}
            {...restProps}
        />
    )
}